import socket
import select
import Queue

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ("127.0.0.1", 8888)
serversocket.bind(server_address)
serversocket.listen(10)
print  "started:" , server_address
serversocket.setblocking(False)
timeout = 10
epoll = select.epoll()
epoll.register(serversocket.fileno(), select.EPOLLIN)
message_queues = {}
fd_to_socket = {serversocket.fileno():serversocket,}

while True:
    print "listening..."
    events = epoll.poll(timeout)
    if not events:
        print "reepoll......"
        continue
    print "have" , len(events), "new events......"

    for fd, event in events:
        socket = fd_to_socket[fd]
        if socket == serversocket:
            connection, address = serversocket.accept()
            print "newconn:" , address
            connection.setblocking(False)
            epoll.register(connection.fileno(), select.EPOLLIN)
            fd_to_socket[connection.fileno()] = connection
            message_queues[connection]  = Queue.Queue()
        elif event & select.EPOLLHUP:
            print 'client close'
            epoll.unregister(fd)
            fd_to_socket[fd].close()
            del fd_to_socket[fd]
        elif event & select.EPOLLIN:
            data = socket.recv(1024)
            if data:
                print "recv:" , data , "client:" , socket.getpeername()
                message_queues[socket].put(data)
                epoll.modify(fd, select.EPOLLOUT)
        elif event & select.EPOLLOUT:
            try:
                msg = message_queues[socket].get_nowait()
            except Queue.Empty:
                print socket.getpeername() , " queue empty"
                epoll.modify(fd, select.EPOLLIN)
            else :
                print "send" , data , "client:" , socket.getpeername()
                socket.send(msg)

epoll.unregister(serversocket.fileno())
epoll.close()
serversocket.close()